package cn.jdy.authority.service;

import cn.jdy.authority.entity.SysRole;
import cn.jdy.authority.entity.User;
import cn.jdy.authority.entity.UserRole;
import cn.jdy.framework.constant.BaseConstant;
import cn.jdy.framework.db.hibernate.BaseDao;
import cn.jdy.framework.exception.BaseException;
import cn.jdy.framework.log.BaseLog;

import com.mysql.jdbc.StringUtils;

import org.hibernate.FetchMode;
import org.hibernate.SQLQuery;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.MatchMode;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Restrictions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * 系统用户信息管理业务处理接口实现类
 *
 * @author XiaoZhenx
 * @description: 针对系统用户信息管理业务处理管理接口的实现
 * @date 2013-07-08 10:10
 */
@Service
public class UserService extends BaseDao<User> {

	@Autowired
	private UserRoleService userRoleManage;

	/**
	 * 用户信息列表 查询
	 *
	 * @return list<user> 用户信息(user)列表
	 * @description: 根据页面不同查询条件 获取系统用户列表信息
	 * @param: map 用户信息查询条件
	 * @param: curNo 列表查询当前页码
	 * @param: curSize 最大记录位置
	 * @author: XiaoZhenx
	 * @date: 2013-07-08 10:20
	 */
	@SuppressWarnings("unchecked")
	public List<User> findUserInfoList(Map<String, String> map, int firstResult, int maxResults) {
	  DetachedCriteria dc =  DetachedCriteria.forClass(entityClass);
		try {
		  dc.addOrder(Order.desc("createTime"));
		  return super.find(dc, firstResult, maxResults);
		} catch(Exception e) {
			BaseLog.e(this.getClass(), "findUserInfoList 系统用户列表信息查询", e);
			throw new BaseException("根据页面查询条件查询系统用户列表信息出错！", e);
		}
	}

	/**
	 * 用户信息列表 总条数查询
	 *
	 * @return int 不同条件查询的总记录条数
	 * @description: 根据不同查询条件 获取系统用户列表总记录条数
	 * @param: map 用户信息查询条件
	 * @author: XiaoZhenx
	 * @date: 2013-07-08 10:20
	 */
	public long findUserInfoListCount(Map<String, String> map) {
		DetachedCriteria dc = DetachedCriteria.forClass(super.entityClass);
		Set<String> set = map.keySet();
		for(String key : set) {
			if(!StringUtils.isNullOrEmpty(map.get(key))) dc.add(Restrictions.eq(key, map.get(key)));
		}
		return super.count(dc);
	}

	@SuppressWarnings("finally")
	@Transactional
	public String addUser(User user) {
		String backInfo = "200";
		try {
			user.setId(null);
			DetachedCriteria dc = DetachedCriteria.forClass(super.entityClass);
			dc.add(Restrictions.eq("username", user.getUsername()));
			int count = count(dc).intValue();
			if(count == 0) {
				super.save(user);
				if (!"".equals(user.getRoleid())) {
					String[] roleId = user.getRoleid().split(",");
					for(String id : roleId) {
						// 循环添加用户多角色
						UserRole role = new UserRole();
						role.setId(null);
						role.setRoleid(id);
						role.setUserid(user.getId());
						userRoleManage.save(role);
					}
				}

			} else {
				backInfo = "409";
				BaseLog.e(this.getClass(), user.getUsername() + ":此用户名已存在");
			}
		} catch(Exception e) {
			backInfo = "500";
			BaseLog.e(this.getClass(), "addUser 添加运维人员", e);
			throw new BaseException(" 添加运维人员出错！", e);
		}
		return backInfo;
	}

	/**
	 * 用户信息 修改
	 *
	 * @return String 修改用户信息的成功、失败信息
	 * @description: 修改系统用户的信息, 对系统用户信息的修改操作
	 * @param: user 系统用户信息实体类
	 * @author: XiaoZhenx
	 * @date: 2013-07-08 10:30
	 */
	@SuppressWarnings("finally")
	@Transactional
	public String updUser(User user) {
		String backInfo = "0";
		try {
			super.updateWithValidator(user);
			// 添加用户对应角色关系
			String roleId = user.getRoleid();
			String[] ids = roleId.split(",");
			if(!"".equals(roleId) && ids.length != 0) {
				// 删除用户角色
				userRoleManage.delete("userid", user.getId());
				for(String id : ids) {
					// 循环添加用户多角色
					UserRole role = new UserRole();
					role.setRoleid(id);
					role.setUserid(user.getId());
					userRoleManage.save(role);
				}
			}
			backInfo = "1";
		} catch(Exception e) {
			BaseLog.e(this.getClass(), "upSysOper 修改运维人员", e);
			throw new BaseException("修改运维人员出错！", e);
		}
		return backInfo;
	}

	/**
	 * 用户信息 删除
	 *
	 * @return String 删除用户信息的成功、失败信息
	 * @description: 删除指定用户标识的系统用户信息, 对多个系统用户信息的删除操作
	 * @param: userId 用户标识（多个用户时用,号隔开）
	 * @author: XiaoZhenx
	 * @date: 2013-07-08 16:40
	 */
	@Transactional
	public String delUserById(String userIds) {
		String backInfo = "0";
		try {
			String[] ids = userIds.split(",");
			// 删除用户
			super.delete(ids, "id");
			// 删除用户角色
			userRoleManage.delete(ids, "userid");
			backInfo = "1";
		} catch(Exception e) {
			backInfo = "0"; // 删除失败
			BaseLog.e(this.getClass(), "delSysOper 删除运维人员", e);
			throw new BaseException("删除运维人员出错！", e);
		}
		return backInfo;
	}

	/**
	 * 用户密码重置
	 *
	 * @return String
	 * @description: 对多个系统用户密码重置 操作
	 * @param: userId 用户标识（多个用户时用,号隔开）
	 * @author: XiaoZhenx
	 * @date: 2013-07-08 16:40
	 */
	@Transactional
	public String resetPassword(String userIds, String password) {
		String backInfo = "0";
		try {
			DetachedCriteria dc = DetachedCriteria.forClass(super.entityClass);
			dc.add(Restrictions.in("id", userIds.split(",")));
			List<User> userList = find(dc);
			for(User user : userList) {
				user.setPasswd(password);
				super.update(user);
			}
			backInfo = "1";
		} catch(Exception e) {
			backInfo = "0";
			BaseLog.e(this.getClass(), "resetPassword 用户密码重置 ", e);
			throw new BaseException("用户密码重置 出错！", e);
		}
		return backInfo;
	}

	/**
	 * 用户信息 启用和停用操作
	 *
	 * @return String 用户状态信息的更新成功、失败信息
	 * @description: 启用和停用指定用户标识的系统用户信息。 启用操作是将用户从锁定状态修改为正常状态 停用操作是将用户从正常状态修改为锁定状态
	 * @param: userIds 用户标识（多个用户时用,号隔开）
	 * @param: status 操作状态（1 启用 0 停用）
	 * @author: XiaoZhenx
	 * @date: 2013-07-10 16:40
	 */
	@Transactional
	@CacheEvict(value = "cache1", key = "'userRole_'+#userId")
	public String updUserStatus(String userIds, String status) {
		String backInfo;
		try {
			DetachedCriteria dc = DetachedCriteria.forClass(super.entityClass);
			dc.add(Restrictions.in("id", userIds.split(",")));
			List<User> userList = find(dc);
			if(BaseConstant.USER_OPER_ENABLE.equals(status) || BaseConstant.USER_OPER_DISABLE.equals(status)) {
				for(User user : userList) {
					user.setStatus(status);
					super.update(user);
				}
				backInfo = "1";
			} else {
				backInfo = "0";
				BaseLog.e(this.getClass(), "操作状态出错");
			}

		} catch(Exception e) {
			BaseLog.e(this.getClass(), "用户信息出错", e);
			throw new BaseException("启用、停用用户信息出错！", e);
		}
		return backInfo;
	}

	/**
	 * :根据用户ID查询用户角色
	 *
	 * @param : String userId
	 * @return :List<String>
	 */
	@Cacheable(value = "cache1", key = "'userRole_'+#userId")
	public List<String> findUserRole(String userId) {
		List<String> list = new ArrayList<String>();
		try {
			List<UserRole> roles = userRoleManage.find("userid", userId);
			for(UserRole role : roles) {
				list.add(role.getRoleid());
			}
		} catch(Exception e) {
			BaseLog.e(this.getClass(), "根据用户ID查询用户角色出错", e);
			throw new BaseException("根据用户ID查询用户角色出错！", e);
		}
		return list;
	}


	/**
	 * 修改用户密码
	 */
	public boolean modifyPwd(String id, String password) {
		User user = super.find(id);
		user.setPasswd(password);
		super.update(user);
		if(null != user) return true;
		else return false;
	}
	
	public int countUsers(String roleid) {
		int count = 0;
		try {
			SQLQuery query = super.em().createSQLQuery("SELECT COUNT(0) FROM user u WHERE NOT EXISTS (SELECT 1 FROM userrole r WHERE r.userid = u.id AND r.roleid = ?)");
			query.setParameter(0, roleid);
			count = Integer.parseInt(String.valueOf(query.uniqueResult()));
		} catch(Exception e) {
			BaseLog.e(this.getClass(), "查询会员信息异常", e);
		}
		return count;
	}

	/**
   * 查询用户列表
   */
  public List<User> findUsers(String roleid, int iDisplayStart, int iDisplayLength) {
    try {
//      DetachedCriteria dc = DetachedCriteria.forClass(entityClass);
//      dc.setFetchMode("userrole",  FetchMode.EAGER);
//      dc.createAlias("userrole", "ur");
//      dc.add(Restrictions.ne("ur.roleid", roleid));
//      // dc.add(Restrictions.not(Restrictions.like("roleid", roleid, MatchMode.ANYWHERE)));
//      return super.find(dc);
      
      String sql = "select * from user u" +
              " where 1=1 and not exists (select 1 from userrole r" +
              " where r.userid = u.id and r.roleid = ?) limit ?,?";
      SQLQuery query = super.em().createSQLQuery(sql).addEntity(entityClass);
      query.setParameter(0, roleid);
      query.setParameter(1, iDisplayStart);
      query.setParameter(2, iDisplayLength);
      return  query.list();
      
    } catch(Exception e) {
      BaseLog.e(this.getClass(), "findUsers查询用户列表失败", e);
    }
    return null;
  }
  
  /**
   * 根据角色查询用户
   * @param role
   * @return
   */
  public List<User> findUserByRoleId(SysRole role) {
    try {
//      DetachedCriteria dc = DetachedCriteria.forClass(entityClass);
//      dc.setFetchMode("userrole", FetchMode.JOIN);
//      dc.createAlias("userrole", "ur");
//      dc.add(Restrictions.eq("ur.roleid", role.getId()));
//      // dc.add(Restrictions.like("roleid" ,role.getId(), MatchMode.ANYWHERE));
//      return super.find(dc, role.getiDisplayStart(), role.getiDisplayLength());
      
      String sql = "select * from user u" +
              " where 1=1 and exists (select 1 from userrole r" +
              " where r.userid = u.id and r.roleid = ?) limit ?, ?";
      SQLQuery query = super.em().createSQLQuery(sql).addEntity(entityClass);
      query.setParameter(0, role.getId());
      query.setParameter(1, role.getiDisplayStart());
      query.setParameter(2, role.getiDisplayLength());
      return  query.list();
      
    } catch(Exception e) {
      BaseLog.e(this.getClass(), "findUserByRoleId根据角色id分页查找用户失败", e);
    }
    return null;
  }
  
  
  
  
  /**
   * 根据角色查询用户
   * @param role
   * @return
   */
  public List<User> findUserByRoleName(SysRole role) {
    try {
      String sql = "select * from user u" +
              " where 1=1 and exists (select 1 from userrole r" +
              " where r.userid = u.id and r.roleid = ?)";
      SQLQuery query = super.em().createSQLQuery(sql).addEntity(entityClass);
      query.setParameter(0, role.getId());
      return  query.list();
      
    } catch(Exception e) {
      BaseLog.e(this.getClass(), "findUserByRole根据角色id查找用户失败", e);
    }
    return null;
  }
  

  /**
	 * 根据用户名查找用户
	 *
	 * @param username
	 * @return
	 */
	public User findMemberByUsername(String username) {
	  DetachedCriteria dc = DetachedCriteria.forClass(entityClass);
	  dc.add(Restrictions.or(Restrictions.eq("username", username),Restrictions.eq("mobile", username)));
	  return super.findOne(dc);
	}
}
